package client

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"sync"
	"time"
	"wxp2p/common"
)

// 远程连接<-->local:2222<-->client_client<-->webrtcdatachannel<-->server_client<-->local:3389

var id_conn_map_nutex sync.RWMutex
var id_conn_map = make(map[string]net.Conn, 0)

func ServerRecvChanHandler(port string) { //3389
	for buf := range LocalPortRecvChan {
		id, action, content := common.UnPackageData(buf)
		switch action {
		case "data":
			id_conn_map_nutex.RLock()
			conn, bHave := id_conn_map[id]
			id_conn_map_nutex.RUnlock()
			if bHave {
				_, err := conn.Write([]byte(content))
				if err != nil {
					log.Println(err)
					id_conn_map_nutex.Lock()
					delete(id_conn_map, id)
					id_conn_map_nutex.Unlock()
					LocalPortSendChan <- common.PackageData(id, "close", "")
				}
			} else {
				log.Println("1.出错了，应该存在的连接失败了")
			}
		case "new":
			conn, err := net.DialTimeout("tcp", "127.0.0.1:"+port, 2*time.Second)
			if err != nil {
				log.Println("dial error:", err)
				return
			}
			id_conn_map_nutex.Lock()
			id_conn_map[id] = conn
			id_conn_map_nutex.Unlock()
			// 接收数据的线程,接收2222的数据
			go func() {
				buf := make([]byte, 60535)
				reader := bufio.NewReader(conn)
				defer func() {
					conn.Close()
					id_conn_map_nutex.Lock()
					delete(id_conn_map, id)
					id_conn_map_nutex.Unlock()
					LocalPortSendChan <- common.PackageData(id, "close", "")
				}()
				for {
					cnt, err := reader.Read(buf)
					if cnt == 0 || err != nil {
						break
					}
					LocalPortSendChan <- common.PackageData(id, "data", string(buf[0:cnt]))
				}
			}()
		case "close":
			id_conn_map_nutex.RLock()
			conn, bHave := id_conn_map[id]
			id_conn_map_nutex.RUnlock()
			if bHave {
				conn.Close()
				id_conn_map_nutex.Lock()
				delete(id_conn_map, id)
				id_conn_map_nutex.Unlock()
			} else {
				log.Println("2.出错了，应该存在的连接失败了")
			}
		}
	}
}

// client-client监听，接收新连接
func ListenLocalTCP(port string) {
	listen, err := net.Listen("tcp", ":"+port)
	if err != nil {
		fmt.Println("listen error: ", err)
		return
	}

	for {
		//一次请求，另一个client就得dial一次，所以data channel不能只传输数据，还得传输命令，两边得定义规则识别每次accept,需要把接收到的数据对应发送到客户端
		conn, err := listen.Accept() //2222
		if err != nil {
			fmt.Println("accept error: ", err)
			break
		}

		log.Println("new conn:", conn.RemoteAddr().String())
		connId := conn.RemoteAddr().String()
		id_conn_map_nutex.Lock()
		id_conn_map[connId] = conn
		id_conn_map_nutex.Unlock()
		LocalPortSendChan <- common.PackageData(connId, "new", "-")
		// read
		go func() {
			defer func() {
				conn.Close()
				id_conn_map_nutex.Lock()
				delete(id_conn_map, connId)
				id_conn_map_nutex.Unlock()
				LocalPortSendChan <- common.PackageData(connId, "close", "-")
			}()
			if conn == nil {
				log.Panic("无效的 socket 连接")
			}
			buf := make([]byte, 60535)
			reader := bufio.NewReader(conn)
			for {
				cnt, err := reader.Read(buf)
				if cnt == 0 || err != nil {
					// conn.Close()
					break
				}
				LocalPortSendChan <- common.PackageData(connId, "data", string(buf[0:cnt]))
			}
		}()
	}
}
func ClientLocalRecvChanHandler() {
	for buf := range LocalPortRecvChan {
		id, action, content := common.UnPackageData(buf)
		switch action {
		case "data":
			id_conn_map_nutex.RLock()
			conn, bHave := id_conn_map[id]
			id_conn_map_nutex.RUnlock()
			if bHave {
				_, err := conn.Write([]byte(content))
				if err != nil {
					log.Println(err)
					id_conn_map_nutex.Lock()
					delete(id_conn_map, id)
					id_conn_map_nutex.Unlock()
					LocalPortSendChan <- common.PackageData(id, "close", "")
				}
			} else {
				log.Println("3.出错了，应该存在的连接失败了")
			}
		case "close":
			id_conn_map_nutex.RLock()
			conn, bHave := id_conn_map[id]
			id_conn_map_nutex.RUnlock()
			if bHave {
				conn.Close()
				id_conn_map_nutex.Lock()
				delete(id_conn_map, id)
				id_conn_map_nutex.Unlock()
			}
		}
	}
}
